package com.oracleoaec.view;

import java.util.ArrayList;
import java.util.List;

import com.oracleoaec.client.Client;
import com.oracleoaec.entity.Brand;
import com.oracleoaec.entity.Car;
import com.oracleoaec.entity.Category;
import com.oracleoaec.entity.Record;
import com.oracleoaec.entity.User;
import com.oracleoaec.util.InputException;
import com.oracleoaec.util.JsonMapper;
import com.oracleoaec.util.QRcodeImage;
import com.oracleoaec.util.ScannerUtil;
import com.oracleoaec.util.Util;

public class LoginView extends Client {
	// 对象与JSON字符串转换的工具类
	private JsonMapper binder = JsonMapper.nonDefaultMapper();

	public void operation() {
		boolean isExist=false;
		Integer num=null;
		while(true) {
			init();
			//输入操作1,登录，2注册,3退出!并且捕获了输入异常
			if((num=InputException.inputException())==null){
				continue;
			}
			//num=1代表是登陆(给一个标识判断是什么类型用户登陆type=0 or 1)，
			//2是代表是注册
			switch(num){
			case 1://登陆成功之后的操作很多
				//在判断是什么类型用户登陆(0普通人，1管理员)
				num = InputException.input("请输入你的身份类型：0->普通人,1->管理员");
				String reg3="[0-1]";
				while(!(num+"").matches(reg3)){
					num = InputException.input("☛请重新输入你的身份类型：普通人(0),管理员(1)");	
				}
				if(0==num){//普通用户登陆
					User user=login(num);//普通用户登陆方法
					if(user!=null){		 //不为null就是用户登陆成功
						System.out.println("欢迎--------《"+user.getUserName()+"》---------登陆二嗨系统");
						
						//一开始展示一下所有车
						//发送请求要求服务器给我所有的汽车信息(返回的是json格式)，
						showAllCarInfo(num,null,num);
						
						//显示所有的汽车信息
						while(true){
							//显示用户的所有操作
							UserView.userLoginUI();
							boolean flag=false;
							String input=ScannerUtil.next();
							
							//2+1//切割
							String[] s=input.split("\\+");//这里需要使用转义字符，否则会报错
							//这个正则表达式用于判断是否正确输入数字
							@SuppressWarnings("unused")
							String regex=""+s[0]+"\\+[1-2]+";
							//这个提示信息只是用来提示用户品牌和类型找不到使用的
							String tipInfo="输入不合法,正确输入格式是:"+s[0]+"+整数";
							String tipInfo2=tipInfo+"[1-2]!";
							
							switch(s[0]){//1,2,3,4,5,6,7,退出时0
							case "1":
								//使用正则表达式进行判断输入的是否是数字
								//表示整年输入1+正数多为也可以
								String regex1="1\\+\\d+";
								if(input.matches(regex1)){//用户可能会输入：1+43  1+   1+a 1+abc
									//发送请求我要租车,并且返回租车记录
									String recordStr=request("rentCar?"+input+"&"+user.getId());
									Record record=binder.fromJson(recordStr, Record.class);
									if(record!=null){
										System.out.println("编号\t汽车名称\t每日租金\t备注\t品牌\t类型\t借车时间");
										Car car=record.getCar();
										System.out.println(car.getId()+"\t"+car.getModel()+"\t"+car.getRent()+"\t"+car.getComments()+"\t"+car.getBrandName()+"\t"+car.getTypeName()+"\t"+record.getStart_date());
									}else{
										System.out.println("暂时不能借该车");
									}
								}else{
									System.out.println("输入不合法,正确输入格式是:1+整数!");
								}
								break;
								
							case "2":
								//用户对车子的排序查看(2+1将序排序,2+2升序排序)
								String regex2="2\\+[1-2]";
								showCarBrandAndCateg("没有车可以排序",tipInfo2,input,regex2,num);
								break;
							case "3":
								//用户输入(3+类型编号)查看车子的信息
								String regex3="3\\+\\d+";
								showCarBrandAndCateg("对不起,暂时还没有该类型的车子!",tipInfo,input,regex3,num);
								break;
							case "4":
								String regex4="4\\+\\d+";
								//用户输入(3+品牌编号)查看车子的信息
								showCarBrandAndCateg("对不起,没有该品牌的车子!",tipInfo,input,regex4,num);
								break;
							case "5":
								//用户输入5  查看所有的汽车，用户还可以输入5+ 5+a 5+234
								//适当的增加一点容错性，让用户方便点使用
								if(!showAllCarInfo(num,input,num)){
									System.out.println("没有汽车记录!");
								}
								break;
							case "6":
								//用户 输入6 查看我的租车记录 ,在这里用户也可输入6+等 增加容错性能!
								String str6=request("searchAllCar?"+user.getId());
								List<Record> listRecord=binder.fromJson(str6, binder.contructCollectionType(ArrayList.class, Record.class));
								if(listRecord.size()!=0){
									System.out.println("编号\t汽车名称\t总租金\t每日租金\t备注\t品牌\t类型\t借车时间\t\t还车时间");
									for(Record re:listRecord){
										System.out.println(re.toString3());
									}
								}else{
									System.out.println("你暂时还没有租车记录!");
								}
							break;
							case "7":
								//"输入7+汽车编号  还车"
								String recordStr2=request("returnCar?"+input+"&"+user.getId());
								Record record2=binder.fromJson(recordStr2, Record.class);
								if(record2!=null){
									System.out.println("编号\t总租金\t汽车名称\t每日租金\t备注\t品牌\t类型\t借车时间\t\t还车时间");
									System.out.println(record2.toString2());
								}else{
									System.out.println("暂时不能还该车");
								}
							break;
							case "0"://退出,返回上一层界面!
								flag=true;
								break;
							default:System.out.println("输入非法，请重新输入【0-7】！");break;
							}
							if(flag){
								System.out.println("返回上一层界面!");
								break;
							}
						}
					}
				}
				
				
				/*===============管理员的操作===============*/
				if(1==num){//管理员登陆
					User user=login(num);//普通用户登陆方法
					if(user!=null){
						System.out.println("欢迎管理员-----"+user.getUserName()+"-----登陆二嗨系统");
						
						//显示所有管理员可以看到的汽车信息,包括下架的汽车
						showAllCarInfo(num,null,num);
						
						while(true){
							//显示用户的所有操作
							AdminView.adminOperUI();
							boolean flag=false;//这个flag用于返回到登录界面
							
							String input=ScannerUtil.next();
							//2+1//切割
							String[] s=input.split("\\+");//这里需要使用转义字符，否则会报错
							//用户判断是否正确输入操作
							@SuppressWarnings("unused")
							String regex=""+s[0]+"\\+[1-2]+";
							
							String tipInfo="输入不合法,正确输入格式是:"+s[0]+"+整数!";
							String tipInfo2="输入不合法,正确输入格式是:"+s[0]+"+整数[1-2]!";
							switch(s[0]){
							case "1":
								//管理员输入1+汽车编号 查看指定汽车信息
								adminSearchCarById(input, s);
								break;
							case "2":
								String regex2="2\\+[1-2]";
								showCarBrandAndCateg("没有车可以排序",tipInfo2,input,regex2,num);
								break;
							case "3":
								String regex3="3\\+\\d+";
								showCarBrandAndCateg("没有该类型的车子!",tipInfo,input,regex3,num);
								break;
							case "4":
								String regex4="4\\+\\d+";
								showCarBrandAndCateg("没有该品牌的车子!",tipInfo,input,regex4,num);
								break;
							case "5":
								//显示所有汽车信息
								if(!showAllCarInfo(num,input,num)){
									System.out.println("没有汽车记录!");
								}
								break;
							case "6":
								//输入6  添加汽车
								//显示所有的品牌信息
								adminAddCar();
							break;
							case "7":
								//管理员修改汽车信息
								//s是String[] s=input.split("\\+");
								String reg2="7\\+\\d+";
								if(input.matches(reg2)){
									adminUpdateCar(s);
								}else{
									System.out.println("输入非法字符,正确格式(7+整数)");
								}
							break;
							case "8":
								adminSeachCar();
								break;
							case "0":
								flag=true;
								break;
							default:System.out.println("输入非法，请重新输入！");break;
							}
							if(flag){
								System.out.println("返回上一层界面!");
								break;
							}
						}
					}
				}
				break;
			case 2://用户注册
				register();
				break;
			case 3:
				isExist=true;
				System.out.println("退出二嗨系统!");
				break;
			default:
				System.out.println("输入不合法,输入1-3之间的整数！!");
				break;
			}
			if(isExist){
				break;
			}
		}
	}

	private void adminSearchCarById(String input, String[] s) {
		String reg=s[0]+"\\+\\d+";
		if(input.matches(reg)){
			//s[1]就是汽车的编号
			String str=request("findCarById?"+s[1]+"");
				//找到了该车并显示出来
			Car c=binder.fromJson(str, Car.class);
			if(c!=null){
				System.out.println("编号\t汽车名称\t备注\t品牌\t类型\t价格\t是否可租\t是否上架");
				System.out.println(c.toString()+"\t"+(c.getUserable()==0?"上架":"下架"));
			}else{
				System.out.println("没有该汽车存在！");
			}
		}else{
			System.out.println("输入非法字符!正确输入格式是(1+整数)");
		}
	}

	private void adminSeachCar() {
		boolean flag2=false;
		//System.out.println();
		String info="1:查看汽车记录   2:按照用户编号查看汽车   3:按照汽车编号查看汽车";
		while(true){
			int a=InputException.input(info);
			String recordStr=null;
			switch(a){
			case 1:
				recordStr=request("findAllRecord?"+a+"&100");
				//转化为list进行显示
				showAllRecord(recordStr);
				
				flag2=true;
				break;
			case 2:
				int userId=InputException.input("☛请输入你要查询的用户ID号：");
				recordStr=request("findAllRecord?"+a+"&"+userId+"");
				
				showAllRecord(recordStr);
				flag2=true;
				break;
			case 3:
				int carId=InputException.input("☛请输入你要查询的汽车ID号：");
				recordStr=request("findAllRecord?"+a+"&"+carId+"");
				
				showAllRecord(recordStr);
				flag2=true;
				break;
			default:
				System.out.println("请正确输入你要的操作序号!");
				flag2=true;
				break;
			}
			if(flag2){
				break;
			}
		}
	}

	private void adminUpdateCar(String[] s) {
		//输入7+汽车编号  修改汽车信息 修改汽车租赁价格,修改汽车上架、下架
		//注意：汽车下架后，用户不可见"
		//修改之前必须判断是否存在这辆车
		//先根据ID号判断是否存在该车
		String str2=request("isExistCar?"+s[1]);
		Car car=binder.fromJson(str2, Car.class);
		if(car==null){
			System.out.println("该车不存在!");
		}else{
			//车存在才可以进行修改
			if(car.getStatus()==1){//判断是否被用户租出
				System.out.println("该车已经被客户租用，暂时不能修改!");
			}else{
				//这个时候就可以进行修改了
				//System.out.println("可以修改该汽车");
				//int nn=ScannerUtil.nextInt();
				int nn=InputException.input("1：租车价格   2：上架下架");
				String info="编号\t汽车名称\t备注\t品牌\t类型\t价格\t是否可租\t是否上架";
				if(1==nn){//开始修改租金价格
					double pri=InputException.input("请输入租车的价格!");
					String s1=request("updateRent?"+car.getId()+"&"+pri);
					Car c=binder.fromJson(s1, Car.class);
					if(s1!=null){
						System.out.println(info+"\n"+c.toString()+"\t"+(c.getUserable()==0?"上架":"下架"));
					}
				}else if(2==nn){//开始修改上架和下架
					String mess="输入上架(0) 下架(1)，输入对应的数字!";
					int useable=InputException.input(mess);
					String reg="[0-1]";
					while(!(useable+"").matches(reg)){
						//继续输入
						useable=InputException.input("请重新"+mess+"");
					}
					String s1=request("updateUseable?"+car.getId()+"&"+useable);
					Car c=binder.fromJson(s1, Car.class);
					if(s1!=null){
						System.out.println(info+"\n"+c.toString()+"\t"+(c.getUserable()==0?"上架":"下架"));
					}
				}else{
					System.out.println("请输入正确的数字!");
				}
			}
		}
	}

	//管理员添加汽车信息
	private void adminAddCar() {
		String brandStr=request("findAllBrand");//用于显示界面用的数据
		List<Brand> list=binder.fromJson(brandStr, binder.contructCollectionType(ArrayList.class, Brand.class));
		//System.out.println("请选择品牌编号!");
		//遍历所有的那个商品
		if(list!=null){
			for(Brand b:list){
				System.out.println(b.getId()+":"+b.getName());
			}
		}
		//r1,r2用来接收品牌和类型
		//只有这两个都存在才可以进行添加汽车信息
		String r1=null;
		String r2=null;
		int brand=InputException.input("输入品牌ID号：");
		while(true){
			if((r1=request("addCar?"+brand+"&1")).equals("0")){
				//System.out.println("没有该商品，请重新输入");
				//brand=ScannerUtil.nextInt();//没有找到继续输入
				brand=InputException.input("输入错误,请重新输入品牌号：");
			}else{
				//找到了该商品退出
				break;
			}
		}
		
		//显示所有的类型，给管理用来添加使用的
		String categoryStr=request("findAllCategory");
		List<Category> listC=binder.fromJson(categoryStr, binder.contructCollectionType(ArrayList.class, Category.class));
		if(listC!=null){
			for(Category c:listC){
				System.out.println(c.getId()+":"+c.getName());
			}
		}
		int type=InputException.input("输入类型ID号:");
		while(true){
			if((r2=request("addCar?"+type+"&2")).equals("0")){
				type=InputException.input("没有该商品，请重新输入!");
			}else{
				break;//找到了该商品退出
			}
		}
		System.out.print("型号：");
		String model=ScannerUtil.next();
		System.out.print("车牌号；");
		String carNumber=ScannerUtil.next();
		//这里需要进行判断一下车牌号是否存在，存在重新输入
		String carName=request("findCarNumber?"+carNumber);
		while(true){
			if("0".equals(carName)){
				//车牌号不存在,可以注册车牌号
				//System.out.println("车牌号不存在");
				break;
			}else{
				//车牌号已经存在，继续输入车牌号，知道输入对的为止
				System.out.println("车牌号以经存在，请继续输入车牌号");
				carNumber=ScannerUtil.next();
				carName=request("findCarNumber?"+carNumber);
			}
		}
		System.out.print("概要：");
		String comments=ScannerUtil.next();
		System.out.print("颜色：");
		String color=ScannerUtil.next();
		double price=InputException.input("汽车价格：");
		double rent=InputException.input("每日租金：");
		int status=InputException.input("是否可借(0:可借  1:不可借):");
		String reg1="[0-1]";
		while(!(status+"").matches(reg1)){
			System.out.println("请输入正确的数字!");
			status=InputException.input("是否可借(0:可借  1:不可借):");
		}
		//这里可以进行正则表达式来限制他的输入
		int userable=InputException.input("是否上架(0:上架  1:下架):");
		while(!(userable+"").matches(reg1)){
			System.out.println("请输入正确的数字!");
			userable=InputException.input("是否上架(0:上架  1:下架):");
		}
		//接着就是封装车车的信息，发送给服务端进行保存
		if(r1!=null&&r2!=null){//品牌和类型不为空才可以进行添加汽车信息
			Car car=new Car(color, model, carNumber, price, rent, comments, status, userable,brand,type);
			//开始正真的添加车子
			String jsonStr=binder.toJson(car);
			String result=request("realAddCar?"+jsonStr);//将汽车发送给客户端
			if("1".equals(result)){
				System.out.println("添加成功!");
			}else{
				System.out.println("添加失败!");
			}
		}
	}

	private void showAllRecord(String recordStr) {
		List<Record> reList=binder.fromJson(recordStr, binder.contructCollectionType(ArrayList.class, Record.class));
		if(reList.size()==0){
			System.out.println("没有该记录！");
		}else{
			System.out.println("编号\t汽车编号\t汽车名称\t用户编号\t用户名称\t每日租金\t租金总额\t备注\t品牌\t类型\t借车时间\t还车时间");
			for(Record r:reList){
				System.out.println(r.toString());
			}
		}
	}
	
	private void showCarBrandAndCateg(String okayInfo,String falseInfo,String input,String regex,Integer num){
		if(input.matches(regex)){
			if(!showAllCarInfo(num,input,num)){
				System.out.println(okayInfo);
			}
		}else{
			System.out.println(falseInfo);
		}
	}
	
	
	//用户查询所有的汽车信息(包括管理员的显示也在这里)
	private boolean showAllCarInfo(Integer type,String oper,int typee) {
		String carInfoStr=request("searAllCar?sortWary="+oper+"&"+typee+"");
		List<Car> carList=binder.fromJson(carInfoStr, binder.contructCollectionType(ArrayList.class, Car.class));
		if(carList==null){
			System.out.println("此处还没有气车上架");
		}else{
			@SuppressWarnings("unused")
			String info=null;
			String outTip="编号\t汽车名称\t备注\t品牌\t类型\t价格\t是否可租";
			if(type==1){//管理员就可以显示上架
				if(carList.size()==0){//表示没有找到该条数据
					return false;
				}
				System.out.println(outTip+="\t是否上架");
				for(Car car:carList){
					System.out.println(car.toString()+"\t"+(car.getUserable()==0?"上架":"下架"));
				}
			}else{//用户显示可以看得数据
				if(carList.size()==0){//表示没有找到该条数据
					return false;
				}
				System.out.println(outTip);
				for(Car car:carList){
					System.out.println(car.toString());
				}
			}
		}
		return true;
	}

	private static void init() {
		System.out.println("********《欢迎来到二嗨租车系统》*********");
		System.out.println("请选择一下操作：1：登陆!  2：注册!  3：退出系统!");
		System.out.println("请输入你选择的序号：");
	}
	
	//num是判断是什么类型的用户登陆(num:0为普通人，1为管理员(u: admin,p: amdin))
	public User login(Integer num) {
		
		//输入用户登陆信息
		System.out.print("请输入你的用户名：");
		String userName=ScannerUtil.next();
		System.out.print("请输入你的密码：");
		String password=ScannerUtil.next();
		
		//这里开始发送请求给服务器,生成一个随机验证码
		String str=request("getCode");
		System.out.println("在你的D盘已经生成了微信二维码,打开手机扫一扫,输入验证码进行验证!"/*+str*/);
		
		//调用工具类生成二维码验证
		QRcodeImage.getQRcodeImage("The Recode is:"+str+"","D:/recode.jpg");
		
		String re="\\d{4}";
		String in=ScannerUtil.next();
		while(!in.matches(re)){
			System.out.println("输入错误，请重新输入正确的四位验证数字!");
			in=ScannerUtil.next();
		}
		if(in.equals(str)){//验证嘛成功之后就开始用户的信息验证
			//封装成对象然后转化为jackson格式发送给服务器
			User user = new User(userName, password,num);
			user.setType(num);//讲身份传给底层DAO
			String context = "login?username="+user.getUserName()+"&password="+user.getPassword()+"&type="+user.getType()+"";

			//服务器返返回给我的数据库能是0,或者是>0数据
			String response = this.request(context);
			if ("0".equals(response)){
				System.out.println("用户名或密码错误!");
				return null;
			}else {
				System.out.println("恭喜你,登陆成功！");
				return binder.fromJson(response, User.class);
			}
		}else{
			System.out.println("验证码出错,请重新登录！");
			return null;
		}
	}


	//用户注册用来输入用户的信息然后返回一个user对象出去
	private User inputUserInfo() {
		
		System.out.print("请输入你的用户名：");
		String userName=ScannerUtil.next();
		//开始发送请求进行判断名字是否存在
		//如果存在提醒用户继续输入用户名称，知道输入不存在的用户名称
		@SuppressWarnings("unused")
		String str1=request("findUserName?"+userName);
		//返回1表示已经存在,0表示不存在
		while("1".equals(str1)){
			System.out.println("该用户名已经存在,请继续输入用户名称!");
			userName=ScannerUtil.next();
			str1=request("findUserName"+userName);
		}
		
		
		System.out.print("请输入你的密码：");
		String password=ScannerUtil.next();
		
		int sex=InputException.input("请选择性别：0：男生，1：女生");//0或者1
		while(!Util.getString(sex+"").matches("[0-1]{1}")){
			sex=InputException.input("请重新选择性别：0：男生，1：女生");//0或者1
		}
	
		System.out.println("请输入你的身份证：");
		String idNumber=ScannerUtil.next();
		String regIdNum="\\d{17}[0-9a-zA-Z]";
		while(!Util.getString(idNumber).matches(Util.getString(regIdNum))){
			System.out.println("输入不合法,请重新输入你的身份证：");//18位
			idNumber=ScannerUtil.next();
		}
		
		System.out.println("请输入你的手机号：");
		String tel=ScannerUtil.next();
		String regTel="\\d{11}";
		while(!Util.getString(tel).matches(regTel)){
			System.out.println("输入不合法，请输入你的手机号：");
			tel=ScannerUtil.next();
		}
		System.out.print("请输入你的地址：");
		String addr=ScannerUtil.next();
		//全部输入完成确保信息是基本有效的然后发送给服务进行保存到数据库中
		return new User(userName, password,sex, idNumber, tel, addr);
	}
	
	// 注册之前先判断是否包含该名字，有则注册失败,没则注册成功!
	public void register() {
		User user=inputUserInfo();
		String context = "register?" + binder.toJson(user) + "";
		//发送给服务器并返回给消息给我们客户端
		String response = request(context);
		if ("-1".equals(response)) {
			System.out.println("用户名已经存在！");
		} else if ("0".equals(response)) {
			System.out.println("对不起,注册失败！");
		} else if ("1".equals(response)) {
			System.out.println("☛恭喜你,注册成功!");
		}
	}
}
